void*
is a pointer to memory of unknown type, and therefore works outside of the safety net provided by the type system. While it can
be useful in a function body to interface with external code, there is no good reason to step out of the robust C++ type system when defining a
function, either for the function parameters, or for the function return type. For the same reasons, having a member variable of type
void*
is not recommended.
If you want to work with raw memory buffer, use unsigned char *
(or byte *
if your compiler supports it).
If you want to work with different types of data, define a function template and use typed pointers, instead of void *
. If you want a
single object to be able to stores objects of different types, std::any
can also be a type-safe alternative to void*
.
If you want to provide to users of an API an opaque type, declare a type and don’t provide its definition (like with FILE*
).
Note that void*
is commonly used to communicate data of unknown type with C code. This rule will nevertheless raise an issue in this
case, but it can be ignored.
Noncompliant code example
void saveBuffer(void *buffer, size_t size); // Noncompliant
void duplicate(void* destination, size_t count, void *source, size_t size); // Noncompliant
class Process {
// ...
void *userData;
};
using UserData = void*; // Noncompliant
Compliant solution
void saveBuffer(unsigned char *buffer, size_t size);
template<class T>
void duplicate(T* destination, size_t count, T *source);
class Process {
// ...
std::any userData;
};
Exceptions
void*
can be useful when interfacing with C. As such, the rule will ignore extern "C"
functions, as well as types with
standard layout.